package cn.myfirefly.core.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.util.AssertionHolder;

import cn.myfirefly.core.model.Identity;
import cn.myfirefly.core.model.Permission;
import cn.myfirefly.utils.StrUtil;
import cn.myfirefly.utils.WebUtil;

public class MyFireflyFilter implements Filter {

	protected String encoding = "UTF-8";
	
	/**
	 * 例外列表，列表中的动作，任何情况都可以访问
	 */
	private static List<String> excludeList = new ArrayList<String>();
	/**
	 * 不需要检查权限的动作列表，但是需要检查是否登录
	 */
	private static List<String> noCheckPermissionList = new ArrayList<String>();
	protected String loginUrl = "/login.html";
	/**
	 * 没有权限时，跳转的页面
	 */
	protected String noPermitUrl = "/login.html";
	
	public void init(FilterConfig filterConfig) throws ServletException {
		if(filterConfig.getInitParameter("encoding") != null){
			this.encoding = filterConfig.getInitParameter("encoding");
		}
		
		if(filterConfig.getInitParameter("loginUrl") != null){
			this.loginUrl = filterConfig.getInitParameter("loginUrl");
		}
		
		if(filterConfig.getInitParameter("noPermitUrl") != null){
			this.noPermitUrl = filterConfig.getInitParameter("noPermitUrl");
		}
		
		if(filterConfig.getInitParameter("excludeURI") != null){
			String excludeURI = filterConfig.getInitParameter("excludeURI").toString();
			String[] excludeURIs = excludeURI.split(",");
			for(String URI : excludeURIs){
				excludeList.add(URI);
			}
		}
		if(filterConfig.getInitParameter("noCheckPermissionURI") != null){
			String noCheckPermissionURI = filterConfig.getInitParameter("noCheckPermissionURI").toString();
			String[] noCheckPermissionURIs = noCheckPermissionURI.split(",");
			for(String URI : noCheckPermissionURIs){
				noCheckPermissionList.add(URI);
			}
		}
	}

	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        if (request.getCharacterEncoding() == null) {
            if (encoding != null) {
                request.setCharacterEncoding(encoding);// //设置request的编码
            }
        }
        
        String contextPath = request.getContextPath();
        response.setHeader("contextPath", contextPath);
        request.setAttribute("contextPath", contextPath);
        String url = getRequestURL(request);
        if (!StrUtil.equals("/", contextPath)) {
        	url = url.replaceFirst(contextPath, "");
		}
        if (isExclude(url)) {
        	chain.doFilter(servletRequest, servletResponse);
        	return;
		}

        // 判断用户是否已经登录
        HttpSession session = request.getSession();
        Identity identity = (Identity)session.getAttribute("identity");
        if (identity == null && AssertionHolder.getAssertion() != null) {
        	AttributePrincipal principal = (AttributePrincipal)AssertionHolder.getAssertion().getPrincipal();
        	identity = new Identity();
        	identity.setUserSn(Integer.valueOf((String)principal.getAttributes().get("user_sn")));
        	String staffSn = (String)principal.getAttributes().get("staff_sn");
        	identity.setStaffSn(staffSn != null ? Integer.valueOf(staffSn) : null);
        	identity.setLoginName((String)principal.getAttributes().get("login_name"));
        	identity.setUserName((String)principal.getAttributes().get("user_name"));
        	identity.setName((String)principal.getAttributes().get("name"));
        	identity.setStaffNo((String)principal.getAttributes().get("staff_no"));
        	identity.setNickName((String)principal.getAttributes().get("nick_name"));
        	if(principal.getAttributes().get("sex") != null){
        		identity.setSex(((String)principal.getAttributes().get("sex")).toCharArray()[0]);
			}
        	identity.setEmail((String)principal.getAttributes().get("email"));
        	identity.setAddress((String)principal.getAttributes().get("address"));
        	identity.setPhoneNo((String)principal.getAttributes().get("phone_no"));
        	if(principal.getAttributes().get("highest_education") != null){
        		identity.setHighestEducation(((String)principal.getAttributes().get("highest_education")).toCharArray()[0]);
			}
        	identity.setGraduatedFrom((String)principal.getAttributes().get("graduated_from"));
        	identity.setProfession((String)principal.getAttributes().get("profession"));
        	identity.setCredentialNo((String)principal.getAttributes().get("credential_no"));
        	identity.setTitle((String)principal.getAttributes().get("position"));
        	identity.setDepartmentName((String)principal.getAttributes().get("department_name"));
        	identity.setDepartmentSn((Integer)principal.getAttributes().get("department_sn"));
			if(principal.getAttributes().get("credential_type") != null){
				identity.setCredentialType(((String)principal.getAttributes().get("credential_type")).toCharArray()[0]);
			}
			session.setAttribute("identity", identity);
			// 取得用户权限，并放到session
			session.setAttribute("permissions", getPermissions(identity.getLoginName()));
			session.setAttribute("menus", getMenus(identity.getLoginName()));
		} else if (identity == null) {
			if (WebUtil.isAjax(request)) {
				session.setAttribute("identity", null);
    			session.invalidate();
        		response.setHeader("sessionstatus", "timeout");//在响应头设置session状态
			} else {
				session.setAttribute("identity", null);
        		session.invalidate();
        		response.sendRedirect("http://"+ request.getServerName() + ":" + 
        				request.getServerPort() + request.getContextPath() + 
        				this.loginUrl);
			}
			return;
		}
        
        if (isNoCheckPermission(url) || identity.isAdmin()) {
        	chain.doFilter(servletRequest, servletResponse);
        	return;
		}
        
        // 如果已经登录，则判断是否有权限
        @SuppressWarnings("unchecked")
		Map<String, Permission> permissions = (Map<String, Permission>)session.getAttribute("permissions");
        int endIndex = url.indexOf("/", 1);
        if (endIndex < 0) {
        	endIndex = url.length();
		}
        String funId = url.substring(1, endIndex);
        Permission permission = permissions.get(funId);
        if (permission == null || !permission.isPermit(url)) {
        	if (WebUtil.isAjax(request)) {
        		response.setHeader("permissonStatus", "nopermission");
			} else {
        		response.sendRedirect("http://"+ request.getServerName() + ":" + 
        				request.getServerPort() + request.getContextPath() + 
        				this.noPermitUrl);
			}
			return;
		}
        
        chain.doFilter(servletRequest, servletResponse);
	}

	public void destroy() {
		excludeList.clear();
	}

	protected boolean isExclude(String url) {
		if(excludeList.indexOf(url) < 0 ){
			return false;
		}
		return true;
	}
	
	protected boolean isNoCheckPermission(String url) {
		if(noCheckPermissionList.indexOf(url) < 0 ){
			return false;
		}
		return true;
	}
	
	protected String getRequestURL(HttpServletRequest request) {
		String url = request.getRequestURI();
		int endIndex = url.indexOf('?');
		if (endIndex > 0) {
			url = url.substring(0, endIndex + 1);
		}
		endIndex = url.indexOf(';');
		if (endIndex > 0) {
			url = url.substring(0, endIndex + 1);
		}
		
		return url;
	}
	
	/**
	 * 子系统需要实现此方法
	 * @param loginName
	 * @return
	 */
	public Map<String, Permission> getPermissions(String loginName) {
		return null;
	}
	
	/**
	 * 获取子系统的菜单，子系统需要实现此方法
	 * @param loginName
	 * @return
	 */
	public String getMenus(String loginName) {
		return null;
	}
}
